package luke.media.audio;

import javax.sound.sampled.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.*;

// 添加对BeatOverlayProcessor的导入
import luke.audio.metadata.Song;
import luke.audio.metadata.SongMetadataExtractor;
import luke.audio.processor.BeatOverlayProcessor;
import luke.audio.processor.BeatSoundGenerator;
import luke.audio.processor.AudioTranscoder; // 添加AudioTranscoder导入
import luke.audio.processor.PCMAudioProcessor;
import luke.core.controller.PlayController;
import luke.core.logging.LogUtil; // 添加LogUtil导入
import luke.core.utils.JsonUtils;
import luke.core.utils.PlaybackStateManager;


/**
 * 高级音频播放器类
 * 支持可拖动进度条、精确跳转等功能
 */
public class AdvancedAudioPlayer {
    private Clip clip;
    private Clip beatsClip;
    private Clip generalClip;
    private boolean isPlaying = false;
    private final ScheduledExecutorService scheduler;
    private ScheduledFuture<?> progressUpdateTask;
    private File currentAudioFile;
    private long totalDurationMs = 0;// 总时长（毫秒）
    private long currentMs = 0;// 当前播放位置（毫秒）
    private PlaybackStateManager playbackStateManager;

    // BPM和偏移量信息
    private double bpm = 0.0;
    private int beatOffset = 0; // 节拍偏移（毫秒）

    // 进度更新间隔（毫秒）
    private static final int PROGRESS_UPDATE_INTERVAL = 30;
    private SongMetadataExtractor songMetadataExtractor;
    private Map<File, Song> songData;

    private byte[] bytes;

    private int isGeneralClipSuccess;
    private int isBeatsClipSuccess;
    private int isByteSuccess;

    // 音量控制字段
    private FloatControl masterVolumeControl;
    private float currentVolume = 1.0f; // 当前音量(0.0-1.0)

    // 超时时间（毫秒）- 1分钟
    private static final long CLIP_WAIT_TIMEOUT = 60000;

    public AdvancedAudioPlayer() {
        this.scheduler = Executors.newSingleThreadScheduledExecutor();
        this.playbackStateManager = PlaybackStateManager.getInstance();
    }

    public void saveBeatsData(PlayController.BeatsData beatsData) {
        // 查找songData中当前文件的Song对象
        Song song = songData.get(currentAudioFile);
        if (song == null) {
            return;
        }
        if (beatsData.bpm <= 0) {
            return;
        }
        song.setBpm(beatsData.bpm);
        song.setBeatOffset(beatOffset);
        try {
            JsonUtils.writeToJson(song, getJsonFilePath(currentAudioFile));
            // 设置保存成功的状态
            playbackStateManager.setSaveSuccessful(true);
        } catch (IOException e) {
            // 保存失败时设置状态为false
            playbackStateManager.setSaveSuccessful(false);
            throw new RuntimeException(e);
        }
        updateBeat(beatsData);
    }

    /**
     * 获取同名JSON文件路径
     *
     * @param audioFile 音频文件
     * @return JSON文件路径
     */
    private String getJsonFilePath(File audioFile) {
        String audioFileName = audioFile.getName();
        int lastDotIndex = audioFileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            audioFileName = audioFileName.substring(0, lastDotIndex);
        }
        return audioFile.getParent() + File.separator + audioFileName + ".json";
    }

    /**
     * 设置BPM信息
     *
     * @param bpm BPM值
     */
    public void setBpm(double bpm) {
        this.bpm = bpm;
        // 更新PlaybackStateManager中的BPM状态
        if (playbackStateManager != null) {
            playbackStateManager.setBpm(bpm);
        }
    }

    /**
     * 设置节拍偏移
     *
     * @param offset 节拍偏移（毫秒）
     */
    public void setBeatOffset(int offset) {
        this.beatOffset = offset;
        // 更新PlaybackStateManager中的节拍偏移状态
        if (playbackStateManager != null) {
            playbackStateManager.setBeatOffset(offset);
        }
    }

    /**
     * 根据BPM和偏移量计算鼓点位置
     *
     * @param audioDurationMs 音频总时长（毫秒）
     * @return 鼓点位置列表
     */
    public List<Integer> calculateBeatPositions(int audioDurationMs) {
        List<Integer> beatPositions = new ArrayList<>();

        if (bpm <= 0 || audioDurationMs <= 0) {
            LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "BPM或音频时长无效: BPM=" + bpm + ", 时长=" + audioDurationMs);
            return beatPositions;
        }

        // 根据BPM和偏移量生成鼓点
        double beatIntervalMs = 60000.0 / bpm;
        double currentTime = beatOffset;

        LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "鼓点计算参数:");
        LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "  BPM: " + bpm);
        LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "  节拍间隔: " + beatIntervalMs + "ms");
        LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "  偏移量: " + beatOffset + "ms");
        LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "  音频时长: " + audioDurationMs + "ms");

        int beatCount = 0;
        while (currentTime < audioDurationMs) {
            if (currentTime >= 0) { // 只添加非负时间的鼓点
                beatPositions.add((int) Math.round(currentTime));
                if (beatCount < 5) {
                    LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "  鼓点 " + beatCount + ": " + (int) Math.round(currentTime) + "ms");
                }
                beatCount++;
            }
            currentTime += beatIntervalMs;
        }

        LogUtil.debug("AdvancedAudioPlayer", "calculateBeatPositions", "总共生成 " + beatCount + " 个鼓点");

        return beatPositions;
    }

    /**
     * 获取当前的鼓点位置列表
     *
     * @param audioDurationMs 音频总时长（毫秒）
     * @return 鼓点位置列表
     */
    public List<Integer> getBeatPositions(int audioDurationMs) {
        return calculateBeatPositions(audioDurationMs);
    }

    /**
     * 播放音频文件
     *
     * @param audioFile 要播放的音频文件
     */
    public void playByteToClip(File audioFile) {
        // 1,生成音频数据(byte[])
        Semaphore semaphore0 = new Semaphore(0);
        isByteSuccess = 0;
        new Thread(() -> {
            try {
                LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "开始加载音频文件: " + audioFile.getName());
                
                // 使用静态方法处理所有格式
                bytes = AudioTranscoder.convertFileToWAV(audioFile);
                isByteSuccess = 1;
                
                LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "音频文件加载完成，bytes长度: " + (bytes != null ? bytes.length : "null"));
            } catch (Exception e) {
                LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "加载音频文件时出错: " + e.getMessage());
                playbackStateManager.setNotifyErrorMsg("音频文件加载失败: " + e.getMessage());
            } finally {
                // 确保总是释放信号量
                semaphore0.release();
            }
        }).start();
        // 2,分析音频文件BPM和节拍偏移
        int[] flag = {0};
        if (bpm <= 0) {
            try {
                LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "发现bpm为0,开始分析音频文件的BPM和节拍偏移");
                songMetadataExtractor = SongMetadataExtractor.getInstance();
                songData = songMetadataExtractor.getSongData();
                Set<File> files = new HashSet<>();
                files.add(audioFile);
                songMetadataExtractor.batchExtractMetadata(files, 8, new SongMetadataExtractor.AnalysisProgressCallback() {
                    @Override
                    public void onProgressUpdate(String message, int progress, File currentFile) {
                        if (progress == 100) {
                            LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "分析完成");
                            flag[0] = 1;
                        }
                    }

                    @Override
                    public void onFileAnalysisComplete(File file) {

                    }
                });
            } catch (Exception e) {
                playbackStateManager.setNotifyErrorMsg("分析鼓点失败: " + e.getMessage());
                LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "分析鼓点失败: " + e.getMessage());
                // BPM分析失败时，设置flag为1以避免死循环
                flag[0] = 1;
            }
        } else {
            LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "bpm不为0,直接开始播放音频文件");
            flag[0] = 1;
        }
        // 3,将没有鼓点的音频数据输入到generalClip中.

        isGeneralClipSuccess = 0;// 用于判断generalClip是否已经加载了音频数据
        // 等待加载音频bytes数据完成
        try {
            semaphore0.acquire();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        // 检查bytes是否有效
        if (bytes == null || bytes.length == 0) {
            LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "音频数据为空，无法播放");
            return;
        }
        LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "准备加载WAV数据到Clip，bytes长度: " + bytes.length);
        // 将wav输入到generalClip
        try {
            generalClip = loadWAVData(bytes);
            isGeneralClipSuccess = 1;
        } catch (Exception e) {
            LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "加载WAV数据到Clip时出错: " + e.getMessage());
            throw new RuntimeException(e);
        }

        // 4,将鼓点输入到beatsClip中

        isBeatsClipSuccess = 0;// 用于判断beatsClip是否已经加载了音频数据
        LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "当前鼓点Clip正在创建中");
        // 创建一个线程不断循环,直到flag[0] = 1;
        new Thread(() -> {
            // 等待BPM分析完成，最多等待30秒
            long startTime = System.currentTimeMillis();
            long timeout = 30000; // 30秒超时

            // 等待bpm和偏移数据分析完成
            while (flag[0] != 1) {
                // 检查是否超时
                if (System.currentTimeMillis() - startTime > timeout) {
                    LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "BPM分析超时，跳过鼓点生成");
                    flag[0] = 1; // 设置flag以避免死循环
                    break;
                }

                try {
                    Thread.sleep(10); // 短暂休眠，避免过度占用CPU
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    flag[0] = 1; // 设置flag以避免死循环
                    break;
                }
            }

            // 检查songData是否包含当前文件的元数据
            if (songData.containsKey(audioFile)) {
                // 使用setBpm和setBeatOffset方法设置BPM和节拍偏移量
                setBpm(songData.get(audioFile).getBpm());
                setBeatOffset(songData.get(audioFile).getBeatOffset());
                LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "已找到音频文件的元数据，BPM: " + bpm + ", 节拍偏移: " + beatOffset);
            } else {
                LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "未找到音频文件的元数据，使用默认BPM和偏移量");
                // 如果没有找到元数据，设置默认值以避免死循环
                if (bpm <= 0) {
                    setBpm(0); // 默认BPM
                }
                if (beatOffset == 0) {
                    setBeatOffset(0); // 默认偏移量
                }
            }
            // 计算鼓点位置
            LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "鼓点分析完成，开始计算鼓点位置，bytes长度: " + bytes.length);

            List<Integer> calculatedBeatPositions = getBeatPositions(getAudioDurationMs(bytes));

            // 将wav叠加鼓点后输入到beatsClip
            try {
                LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "计算鼓点位置完成，鼓点数量: " + calculatedBeatPositions.size());
                beatsClip = loadWAVDataWithBeats(bytes, calculatedBeatPositions);
                LogUtil.debug("AdvancedAudioPlayer", "playByteToClip", "当前鼓点Clip创建完成");
                isBeatsClipSuccess = 1;
            } catch (Exception e) {
                LogUtil.error("AdvancedAudioPlayer", "playByteToClip", "加载鼓点Clip时出错: " + e.getMessage());
                // 鼓点加载失败时，设置标志以避免死循环
                isBeatsClipSuccess = 1;
            }
        }).start();
        startPlayback();
    }

    public void updateBeat(PlayController.BeatsData beatsData) {
        // 检查当前isGeneralClipSuccess是否成功，最多等待1分钟
        long startTime = System.currentTimeMillis();
        long timeout = CLIP_WAIT_TIMEOUT; // 1分钟超时

        while (isGeneralClipSuccess != 1) {
            // 检查是否超时
            if (System.currentTimeMillis() - startTime > timeout) {
                LogUtil.error("AdvancedAudioPlayer", "updateBeat", "等待generalClip加载超时");
                break;
            }

            try {
                Thread.sleep(50); // 短暂休眠，避免过度占用CPU
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        setBpm(beatsData.bpm);
        setBeatOffset(beatsData.offset);
        isBeatsClipSuccess = 0;
        // 计算鼓点位置
        int audioDurationMs = getAudioDurationMs(bytes);
        List<Integer> calculatedBeatPositions = getBeatPositions(audioDurationMs);

        // 将wav叠加鼓点后输入到beatsClip
        try {
            LogUtil.debug("AdvancedAudioPlayer", "updateBeat", "计算鼓点位置完成，鼓点数量: " + calculatedBeatPositions.size());
            beatsClip = loadWAVDataWithBeats(bytes, calculatedBeatPositions);
            LogUtil.debug("AdvancedAudioPlayer", "updateBeat", "当前鼓点Clip创建完成");
            isBeatsClipSuccess = 1;
        } catch (Exception e) {
            LogUtil.error("AdvancedAudioPlayer", "updateBeat", "加载鼓点Clip时出错: " + e.getMessage());
            // 鼓点加载失败时，设置标志以避免死循环
            isBeatsClipSuccess = 1;
        }
        toStartPlayback(playbackStateManager.isBeatEnabled());
    }

    public void updateBeatVolume(float volume) {
        playbackStateManager.setBeatVolume(volume);
        updateBeat(new PlayController.BeatsData(playbackStateManager.getBpm(), playbackStateManager.getBeatOffset()));
    }

    public void updateBeatSoundType(int soundType) {
        playbackStateManager.setBeatSoundType(soundType);
        updateBeat(new PlayController.BeatsData(playbackStateManager.getBpm(), playbackStateManager.getBeatOffset()));
    }

    /**
     * 更新背景音量
     */
    public void updateBackgroundVolume(float volume) {
        playbackStateManager.setBackgroundVolume(volume);
        updateBeat(new PlayController.BeatsData(playbackStateManager.getBpm(), playbackStateManager.getBeatOffset()));
    }

    /**
     * 在WAV数据上叠加鼓点
     *
     * @param wavData       WAV数据
     * @param beatPositions 鼓点位置列表（毫秒）
     * @return 叠加鼓点后的Clip对象
     * @throws Exception 处理异常
     */
    private Clip loadWAVDataWithBeats(byte[] wavData, List<Integer> beatPositions) throws Exception {
        if (wavData == null || wavData.length == 0) {
            LogUtil.error("AdvancedAudioPlayer", "loadWAVDataWithBeats", "WAV数据为空");
            throw new RuntimeException("WAV数据为空");
        }

        LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "开始加载带鼓点的WAV数据，原始大小: " + wavData.length + " 字节");

        // 在PCM数据上叠加鼓点
        byte[] processedData = wavData;
        LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "叠加鼓点前的数据大小: " + wavData.length + " 字节");
        if (beatPositions != null && !beatPositions.isEmpty()) {
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "在PCM数据上叠加鼓点，鼓点数量: " + beatPositions.size());
            // 获取节拍音量和音效类型
            float beatVolume = playbackStateManager.getBeatVolume();
            int beatSoundType = playbackStateManager.getBeatSoundType();

            // 使用原子操作方法组合实现鼓点叠加功能
            // 1. 从WAV数据中提取PCM数据
            byte[] originalPcm = AudioTranscoder.extractPCMFromWAV(wavData);

            // 2. 生成指定类型的鼓点音效PCM数据
            byte[] beatSoundPcm;
            switch (beatSoundType) {
                case 1:
                    beatSoundPcm = BeatSoundGenerator.generateBubbleSound();
                    break;
                case 2:
                    beatSoundPcm = BeatSoundGenerator.generateDrumSound();
                    break;
                case 3:
                    beatSoundPcm = BeatSoundGenerator.generateTriangleSound();
                    break;
                case 4:
                    beatSoundPcm = BeatSoundGenerator.generateWoodenFishSound();
                    break;
                case 5:
                    beatSoundPcm = BeatSoundGenerator.generateSwordSound();
                    break;
                default:
                    beatSoundPcm = BeatSoundGenerator.generateBeatSound();
                    break;
            }

            // 3. 调整鼓点音效音量
            beatSoundPcm = PCMAudioProcessor.adjustPCMVolume(beatSoundPcm, beatVolume);
            
            // 3.1 调整背景音量
            float backgroundVolume = playbackStateManager.getBackgroundVolume();
            originalPcm = PCMAudioProcessor.adjustPCMVolume(originalPcm, backgroundVolume);

            // 4. 将鼓点音效PCM数据叠加到原始音频PCM数据上
            byte[] processedPcm = BeatOverlayProcessor.overlayBeatSoundOnPcm(originalPcm, beatSoundPcm, beatPositions);

            // 5. 将处理后的PCM数据包装成WAV格式
            processedData = AudioTranscoder.wrapPCMAsWAV(processedPcm);

            LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "叠加鼓点后的数据大小: " + processedData.length + " 字节");
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "数据大小变化: " + (processedData.length - wavData.length) + " 字节");
        } else {
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "没有鼓点需要叠加");
        }

        // 加载处理后的数据到beatsClip
        LogUtil.debug("AdvancedAudioPlayer", "loadWAVDataWithBeats", "加载带鼓点的音频数据到Clip");
        return loadWAVData(processedData);
    }

    /**
     * 获取音频时长（毫秒）
     *
     * @param wavData WAV数据
     * @return 音频时长（毫秒）
     */
    private int getAudioDurationMs(byte[] wavData) {
        if (wavData == null || wavData.length < 44) {
            LogUtil.error("AdvancedAudioPlayer", "getAudioDurationMs", "WAV数据为空或长度不足: " + (wavData != null ? wavData.length : "null"));
            return 0;
        }

        try {
            // 创建音频输入流来获取准确的音频信息
            ByteArrayInputStream bais = new ByteArrayInputStream(wavData);
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(bais);

            // 获取音频格式信息
            AudioFormat format = audioInputStream.getFormat();
            long frameLength = audioInputStream.getFrameLength();
            float sampleRate = format.getSampleRate();
            int frameSize = format.getFrameSize();// 帧大小

            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "音频格式信息:");
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  帧长度: " + frameLength);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  采样率: " + sampleRate);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  帧大小: " + frameSize);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  帧率: " + format.getFrameRate());

            // 关闭音频流
            audioInputStream.close();

            // 使用实际读取的数据大小来计算帧数
            // 实际音频数据大小 = 总大小 - 44字节的WAV文件头
            long actualAudioDataSize = wavData.length - 44;
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "实际音频数据大小: " + actualAudioDataSize + " 字节");

            // 计算帧数
            long calculatedFrameLength = actualAudioDataSize / frameSize;
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "计算得到的帧数: " + calculatedFrameLength);

            // 如果采样率有效，使用计算得到的帧数计算时长
            if (sampleRate > 0) {
                // 时长（毫秒）= (帧数 / 采样率) * 1000
                double durationMs = (calculatedFrameLength / sampleRate) * 1000.0;
                LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "通过计算帧数得到的时长: " + durationMs + " 毫秒");
                return (int) durationMs;
            }

            // 如果采样率无效，回退到文件头解析方法
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "采样率无效，回退到文件头解析方法");
            // 解析WAV文件头获取采样率、位深度和声道数
            int headerSampleRate = byteArrayToInt(wavData, 24);
            int bitsPerSample = byteArrayToShort(wavData, 34);
            int channels = byteArrayToShort(wavData, 22);
            int dataSize = byteArrayToInt(wavData, 40); // 数据块大小在偏移量40处

            // 如果数据块大小看起来不正确，使用总文件大小减去文件头大小
            if (dataSize <= 0 || dataSize > wavData.length) {
                // 通常WAV文件头是44字节
                dataSize = wavData.length - 44;
                LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "使用估算的数据大小: " + dataSize);
            }

            // 添加调试信息
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "WAV文件头解析结果:");
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  采样率: " + headerSampleRate);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  位深度: " + bitsPerSample);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  声道数: " + channels);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  数据大小: " + dataSize);

            // 检查解析结果是否有效
            if (headerSampleRate <= 0) {
                LogUtil.error("AdvancedAudioPlayer", "getAudioDurationMs", "无效的采样率: " + headerSampleRate);
                return 0;
            }
            if (bitsPerSample <= 0) {
                LogUtil.error("AdvancedAudioPlayer", "getAudioDurationMs", "无效的位深度: " + bitsPerSample);
                return 0;
            }
            if (channels <= 0) {
                LogUtil.error("AdvancedAudioPlayer", "getAudioDurationMs", "无效的声道数: " + channels);
                return 0;
            }
            if (dataSize <= 0) {
                LogUtil.error("AdvancedAudioPlayer", "getAudioDurationMs", "无效的数据大小: " + dataSize);
                return 0;
            }

            // 计算时长（毫秒）
            // 时长 = (数据大小 / (位深度/8) / 声道数) / 采样率 * 1000
            int bytesPerSample = bitsPerSample / 8;
            long totalSamples = (long) dataSize / bytesPerSample;
            long durationMs = (totalSamples / channels) * 1000 / headerSampleRate;

            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  每样本字节数: " + bytesPerSample);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  总样本数: " + totalSamples);
            LogUtil.debug("AdvancedAudioPlayer", "getAudioDurationMs", "  计算得到的时长: " + durationMs + " 毫秒");
            return (int) durationMs;
        } catch (Exception e) {
            LogUtil.error("AdvancedAudioPlayer", "getAudioDurationMs", "解析音频时长时出错: " + e.getMessage());
            return 0;
        }
    }

    /**
     * 将字节数组转换为int
     */
    private int byteArrayToInt(byte[] b, int offset) {
        return (b[offset] & 0xFF) |
                ((b[offset + 1] & 0xFF) << 8) |
                ((b[offset + 2] & 0xFF) << 16) |
                ((b[offset + 3] & 0xFF) << 24);
    }

    /**
     * 将字节数组转换为short
     */
    private short byteArrayToShort(byte[] b, int offset) {
        return (short) ((b[offset] & 0xFF) | ((b[offset + 1] & 0xFF) << 8));
    }

    /**
     * 将WAV数据加载到Clip中
     *
     * @param wavData WAV数据
     * @throws Exception 加载异常
     */
    private Clip loadWAVData(byte[] wavData) throws Exception {
        // 检查WAV数据是否有效
        if (wavData == null || wavData.length == 0) {
            LogUtil.error("AdvancedAudioPlayer", "loadWAVData", "WAV数据为空");
            throw new RuntimeException("WAV数据为空");
        }

        LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "开始加载WAV数据，大小: " + wavData.length + " 字节");

        // 验证并修复WAV文件头
        if (wavData.length >= 44) {
            String riff = new String(wavData, 0, 4);
            String wave = new String(wavData, 8, 4);
            String fmt = new String(wavData, 12, 4);
            String data = new String(wavData, 36, 4);
            int dataSize = byteArrayToInt(wavData, 40);

            LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "WAV文件头验证:");
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "  RIFF标识: " + riff);
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "  WAVE标识: " + wave);
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "  fmt标识: " + fmt);
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "  data标识: " + data);
            LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "  数据块大小: " + dataSize);
        }

        // 创建音频输入流
        ByteArrayInputStream bais = new ByteArrayInputStream(wavData);

        // 检查是否是有效的WAV格式
        AudioInputStream audioInputStream;
        try {
            audioInputStream = AudioSystem.getAudioInputStream(bais);
        } catch (Exception e) {
            LogUtil.error("AdvancedAudioPlayer", "loadWAVData", "无法解析WAV数据: " + e.getMessage());
            LogUtil.error("AdvancedAudioPlayer", "loadWAVData", "WAV数据长度: " + wavData.length + " 字节");
            // 尝试打印前几个字节来诊断问题
            if (wavData.length > 0) {
                StringBuilder sb = new StringBuilder("WAV数据前32字节: ");
                for (int i = 0; i < Math.min(32, wavData.length); i++) {
                    sb.append(String.format("%02X ", wavData[i] & 0xFF));
                }
                LogUtil.error("AdvancedAudioPlayer", "loadWAVData", sb.toString());
            }
            throw e;
        }

        LogUtil.debug("AdvancedAudioPlayer", "loadWAVData", "成功创建AudioInputStream");
        Clip clip = loadAudioStream(audioInputStream);

        return clip;
    }

    /**
     * 加载音频流到Clip中
     *
     * @param audioInputStream 音频输入流
     * @throws Exception 加载异常
     */
    private Clip loadAudioStream(AudioInputStream audioInputStream) throws Exception {
        try {
            // 获取音频格式
            AudioFormat format = audioInputStream.getFormat();

            // 打印音频格式信息用于调试
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "音频格式信息:");
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  编码: " + format.getEncoding());
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  采样率: " + format.getSampleRate());
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  声道数: " + format.getChannels());
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  采样位数: " + format.getSampleSizeInBits());
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  帧率: " + format.getFrameRate());
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  帧大小: " + format.getFrameSize());
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "  是否为大端序: " + format.isBigEndian());

            // 创建数据行信息
            DataLine.Info info = new DataLine.Info(Clip.class, format);

            // 检查系统是否支持此音频格式
            if (!AudioSystem.isLineSupported(info)) {
                LogUtil.error("AdvancedAudioPlayer", "loadAudioStream", "不支持的音频格式: " + format);
                throw new LineUnavailableException("不支持的音频格式: " + format);
            }

            Clip newClip = (Clip) AudioSystem.getLine(info);

            // 检查音频数据长度
            long frameLength = audioInputStream.getFrameLength();
            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "音频帧长度: " + frameLength);

            // 读取所有音频数据到字节数组中，以确保数据完整性
            ByteArrayOutputStream audioDataBuffer = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead;
            long totalAudioBytes = 0;
            while ((bytesRead = audioInputStream.read(buffer)) != -1) {
                audioDataBuffer.write(buffer, 0, bytesRead);
                totalAudioBytes += bytesRead;
            }

            LogUtil.debug("AdvancedAudioPlayer", "loadAudioStream", "实际读取的音频数据大小: " + totalAudioBytes + " 字节");

            if (totalAudioBytes <= 0) {
                LogUtil.error("AdvancedAudioPlayer", "loadAudioStream", "音频数据长度无效: " + totalAudioBytes);
                throw new IllegalArgumentException("音频数据长度无效: " + totalAudioBytes);
            }

            // 重新创建AudioInputStream
            ByteArrayInputStream bais = new ByteArrayInputStream(audioDataBuffer.toByteArray());
            AudioInputStream newAudioInputStream = new AudioInputStream(bais, format,
                    totalAudioBytes / format.getFrameSize());
            newClip.open(newAudioInputStream);

            return newClip;
        } catch (IllegalArgumentException e) {
            LogUtil.error("AdvancedAudioPlayer", "loadAudioStream", "加载音频流时发生错误: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 开始播放
     */
    private void startPlayback() {
        // 检查当前isGeneralClipSuccess是否成功，最多等待1分钟
        long startTime = System.currentTimeMillis();
        long timeout = CLIP_WAIT_TIMEOUT; // 1分钟超时

        while (isGeneralClipSuccess != 1) {
            // 检查是否超时
            if (System.currentTimeMillis() - startTime > timeout) {
                LogUtil.error("AdvancedAudioPlayer", "startPlayback", "等待generalClip加载超时");
                break;
            }

            try {
                Thread.sleep(50); // 短暂休眠，避免过度占用CPU
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        // 检查当前是鼓点状态还是普通状态
        boolean beatEnabled = playbackStateManager.isBeatEnabled();
        clip = generalClip;
        if (beatEnabled) {
            LogUtil.debug("AdvancedAudioPlayer", "startPlayback", "当前是鼓点状态,播放应该是鼓点音频");
            if (isBeatsClipSuccess == 1) {
                LogUtil.debug("AdvancedAudioPlayer", "startPlayback", "开始播放鼓点音频");
                clip = beatsClip;// 当前情况万一鼓点音频还没有加载完成,也应该进行播放,当前实现
            } else {
                LogUtil.debug("AdvancedAudioPlayer", "startPlayback", "等待鼓点音频加载完成");
                switchLaterClopPlayback();
            }
        }
        // 检查是否有Clip实例
        if (clip != null) {
            // 设置当前播放的文件
            playbackStateManager.setCurrentFile(currentAudioFile);
            // 设置当前音乐时长
            LogUtil.debug("AdvancedAudioPlayer", "startPlayback", "bytes长度: " + (bytes != null ? bytes.length : "null"));
            totalDurationMs = getAudioDurationMs(bytes);
            playbackStateManager.setTotalDurationMs(totalDurationMs);
            LogUtil.debug("AdvancedAudioPlayer", "startPlayback", "获取的音乐总时长是:" + totalDurationMs);
            setMasterVolume(playbackStateManager.getVolume());
            clip.start();
            // 启动进度更新任务
            startPositionUpdate();
            isPlaying = true;
            playbackStateManager.setIsPlaying(true);
        }
    }

    /**
     * 稍后播放Clip
     */
    private void switchLaterClopPlayback() {
        // 创建一个线程不断循环,直到flag[0] = 1;
        new Thread(() -> {
            LogUtil.debug("AdvancedAudioPlayer", "switchLaterClopPlayback", "等待鼓点音频加载完成...");

            // 等待鼓点音频加载完成，最多等待1分钟
            long startTime = System.currentTimeMillis();
            long timeout = CLIP_WAIT_TIMEOUT; // 1分钟超时

            while (isBeatsClipSuccess != 1) {
                // 检查是否超时
                if (System.currentTimeMillis() - startTime > timeout) {
                    LogUtil.error("AdvancedAudioPlayer", "switchLaterClopPlayback", "等待beatsClip加载超时");
                    break;
                }

                try {
                    Thread.sleep(50); // 短暂休眠，避免过度占用CPU
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }

            LogUtil.debug("AdvancedAudioPlayer", "switchLaterClopPlayback", "鼓点音频已经加载完成");
            LogUtil.debug("AdvancedAudioPlayer", "switchLaterClopPlayback", "当前歌曲" + playbackStateManager.getCurrentFile().getName());
            
            // 确保beatsClip不为null再进行切换
            if (clip != null && beatsClip != null) {
                // 获取当前播放的时间
                long currentPosition = clip.getMicrosecondPosition();
                clip.stop();
                clip = beatsClip;
                clip.setMicrosecondPosition(currentPosition);
                setMasterVolume(playbackStateManager.getVolume());
                if (isPlaying) {
                    clip.start();
                    // 启动进度更新任务
                    startPositionUpdate();
                }
            } else {
                LogUtil.error("AdvancedAudioPlayer", "switchLaterClopPlayback", "clip或beatsClip为null，无法切换");
            }

        }).start();
    }

    /**
     * 切换播放状态（播放/暂停）
     */
    public void togglePlayback(File audioFile) {
        // 检查是否有文件加载
        if (audioFile == null) {
            return;
        }
        LogUtil.debug("AdvancedAudioPlayer", "togglePlayback", audioFile.toString());
        LogUtil.debug("AdvancedAudioPlayer", "togglePlayback", currentAudioFile != null ? currentAudioFile.toString() : "null");
        // 检查当前播放的文件是否与传入的文件相同
        if (currentAudioFile != null && currentAudioFile.equals(audioFile)) {
            LogUtil.debug("AdvancedAudioPlayer", "togglePlayback", "传入的文件和状态保存的文件相同");
            // 如果是相同文件，切换播放状态
            if (isPlaying) {
                pause();
            } else {
                resume();
            }
            return;
        }
        playbackStateManager.setBpm(0);
        playbackStateManager.setBeatOffset(0);
        // 传入的文件与状态保存的文件不同则要加载文件并播放
        LogUtil.debug("AdvancedAudioPlayer", "togglePlayback", "传入的文件和状态保存的文件不同");
        stop();
        bpm = 0;
        beatOffset = 0;
        LogUtil.debug("AdvancedAudioPlayer", "togglePlayback", "重置BPM和节拍偏移");
        // 如果是不同文件，加载新文件并开始播放
        currentAudioFile = audioFile;
        playByteToClip(currentAudioFile);
    }

    /**
     * 启动进度更新任务
     */
    private void startPositionUpdate() {
        stopPositionUpdate(); // 先停止之前的任务

        progressUpdateTask = scheduler.scheduleAtFixedRate(() -> {
            if (clip != null && isPlaying) {
                long currentPositionMs = clip.getMicrosecondPosition() / 1000;
                playbackStateManager.setCurrentPositionMs(currentPositionMs);

                // 检查是否播放完成
                if (currentPositionMs >= totalDurationMs - 100) { // 100ms的容差
                    // 调用播放完成回调，播放下一曲
                    PlayController playController = PlayController.getInstance();
                    playController.playNextTrack();
                }
            }
        }, 0, PROGRESS_UPDATE_INTERVAL, TimeUnit.MILLISECONDS);
    }

    /**
     * 停止进度更新任务
     */
    private void stopPositionUpdate() {
        if (progressUpdateTask != null && !progressUpdateTask.isCancelled()) {
            progressUpdateTask.cancel(false);
            progressUpdateTask = null;
        }
    }

    /**
     * 停止当前播放
     */
    public void stop() {
        // 停止WAV播放
        if (clip != null) {
            try {
                clip.stop();
                clip.close();
            } catch (Exception e) {
                // 忽略异常
            }
            clip = null;
        }
        if (generalClip != null) {
            try {
                generalClip.stop();
                generalClip.close();
            } catch (Exception e) {
                // 忽略异常
            }
            generalClip = null;
        }
        if (beatsClip != null) {
            try {
                beatsClip.stop();
                beatsClip.close();
            } catch (Exception e) {
                // 忽略异常
            }
            beatsClip = null;
        }
        // 停止进度更新
        stopPositionUpdate();
    }

    /**
     * 暂停当前播放
     */
    public void pause() {
        if (clip != null) {
            clip.stop();
            isPlaying = false;
            playbackStateManager.setIsPlaying(false);
            stopPositionUpdate();
        } else {
            LogUtil.error("AdvancedAudioPlayer", "pause", "clip为null，无法暂停播放");
        }
    }

    /**
     * 恢复播放
     */
    public void resume() {
        if (clip != null) {
            clip.setMicrosecondPosition(playbackStateManager.getPlaybackPositionMs() * 1000);
            setMasterVolume(playbackStateManager.getVolume());
            clip.start();
            isPlaying = true;
            playbackStateManager.setIsPlaying(true);
            startPositionUpdate();
        } else {
            LogUtil.error("AdvancedAudioPlayer", "resume", "clip为null，无法恢复播放");
        }
    }

    /**
     * 跳转到指定位置
     *
     * @param positionMs 位置（毫秒）
     */
    public void seekTo(long positionMs) {
        if (clip != null) {
            // 限制位置在有效范围内
            positionMs = Math.max(0, Math.min(positionMs, totalDurationMs));

            // 设置播放位置
            clip.setMicrosecondPosition(positionMs * 1000);
            LogUtil.debug("AdvancedAudioPlayer", "seekTo", "跳转到: " + positionMs * 1000);
            setMasterVolume(playbackStateManager.getVolume());
            // 如果当前是暂停状态，保持暂停；如果是播放状态，继续播放
            if (!isPlaying) {
                clip.stop();
                playbackStateManager.setCurrentPositionMs(positionMs);
            } else {
                clip.start();
            }
        } else {
            LogUtil.error("AdvancedAudioPlayer", "seekTo", "clip为null，无法跳转到指定位置");
        }
    }

    /**
     * 获取当前播放位置（毫秒）
     *
     * @return 当前播放位置（毫秒）
     */
    public long getCurrentPositionMs() {
        if (clip != null) {
            return clip.getMicrosecondPosition() / 1000;
        }
        return 0;
    }

    public void toggleBeatEnabled(boolean newBeatEnabled) {
        if (playbackStateManager.getCurrentFile() == null) {
            return;
        }
        toStartPlayback(newBeatEnabled);
        playbackStateManager.setBeatEnabled(newBeatEnabled);
    }

    /**
     * 切换播放状态
     *
     * @param newBeatEnabled
     */
    private void toStartPlayback(boolean newBeatEnabled) {
        // 检查当前isGeneralClipSuccess是否成功，最多等待1分钟
        long startTime = System.currentTimeMillis();
        long timeout = CLIP_WAIT_TIMEOUT; // 1分钟超时

        while (isGeneralClipSuccess != 1) {
            // 检查是否超时
            if (System.currentTimeMillis() - startTime > timeout) {
                LogUtil.error("AdvancedAudioPlayer", "toStartPlayback", "等待generalClip加载超时");
                break;
            }

            try {
                Thread.sleep(50); // 短暂休眠，避免过度占用CPU
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        
        // 确保clip不为null再获取当前位置
        long currentPosition = 0;
        if (clip != null) {
            currentPosition = clip.getMicrosecondPosition();
            clip.stop();
        }
        
        // 检查当前是鼓点状态还是普通状态
        clip = generalClip;
        if (newBeatEnabled) {
            LogUtil.debug("AdvancedAudioPlayer", "toStartPlayback", "当前是鼓点状态,播放应该是鼓点音频");
            if (isBeatsClipSuccess == 1 && beatsClip != null) {
                LogUtil.debug("AdvancedAudioPlayer", "toStartPlayback", "开始播放鼓点音频");
                clip = beatsClip;// 当前情况万一鼓点音频还没有加载完成,也应该进行播放,当前实现
            } else {
                LogUtil.debug("AdvancedAudioPlayer", "toStartPlayback", "等待鼓点音频加载完成");
                switchLaterClopPlayback();
            }
        }
        
        // 检查是否有Clip实例
        if (clip != null) {
            // 设置播放位置
            clip.setMicrosecondPosition(currentPosition);
            setMasterVolume(playbackStateManager.getVolume());
            if (isPlaying) {
                clip.start();
                // 启动进度更新任务
                startPositionUpdate();
            }
        } else {
            LogUtil.error("AdvancedAudioPlayer", "toStartPlayback", "clip为null，无法播放");
        }
    }

    /**
     * 设置主音量
     *
     * @param volume 音量值(0.0-1.0)
     */
    public void setMasterVolume(float volume) {
        // 限制音量范围在0.0-1.0之间
        volume = Math.max(0.0f, Math.min(1.0f, volume));
        playbackStateManager.setVolume(volume);
        if (clip != null) {
            updateClipVolume(clip, volume);
        }
    }

    /**
     * 更新当前Clip的音量
     */
    private void updateClipVolume(Clip clip, float volume) {
        // 尝试更新当前活动Clip的音量
        Clip activeClip = clip; // 使用当前活动的Clip
        if (activeClip != null && activeClip.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
            FloatControl gainControl = (FloatControl) activeClip.getControl(FloatControl.Type.MASTER_GAIN);
            // 将线性音量值转换为分贝值
            float dB = (float) (20 * Math.log10(volume));
            // 限制在控制的有效范围内
            dB = Math.max(gainControl.getMinimum(), Math.min(gainControl.getMaximum(), dB));
            gainControl.setValue(dB);
        }
    }
}